package com.luoqiuy.poet.service.iml;

import com.luoqiuy.poet.entity.*;
import com.luoqiuy.poet.mapper.*;
import com.luoqiuy.poet.service.AuthorService;
import com.luoqiuy.poet.service.redisService.impl.RedisServiceImpl;
import com.luoqiuy.poet.util.MailUtil;
import com.luoqiuy.poet.util.RandomUtil;
import com.luoqiuy.poet.util.UploadFile;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.List;

@Service
public class AuthorServiceImpl implements AuthorService {


    @Autowired
    private RedisServiceImpl redisService;

    @Autowired
    private AuthorMapper authorMapper;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private PoetMapper poetMapper;
    @Autowired
    private UserDetailInfoMapper userDetailInfoMapper;
    @Autowired
    private FollowMapper followMapper;
    @Autowired
    private IntroductionMapper introductionMapper;
    @Autowired
    private VisitMessageMapper visitMessageMapper;

    @Autowired
    private MailUtil mailUtil;

    public Logger log = LoggerFactory.getLogger(AuthorServiceImpl.class);


    @Override
    public int authorLogin(HttpServletRequest request,Author author) {
        Author au = authorMapper.loadAuthor(author.getUsername());
        if (!au.getPassword().equals(author.getPassword())){
            request.getSession().setAttribute("data",0);
            return 0;
        }
        log.info(author.getUsername() + " login");
        User user =  userMapper.getUserByAuthorId(au.getId());

        //先查询缓存，有则直接返回，没有就直接查询MySQL 并且写入缓存
        List<Poet> books = null;
        try {
            books = redisService.loadPoetsByAuthorId(au.getId());
        }catch (Exception e){
            log.error(e.toString());
        }
        if (null == books){
            books = poetMapper.loadPoetsByAuthorId(au.getId());
            boolean flag = redisService.writePoetCacheByAuthorId(au.getId(),books);
            if (flag){
                log.warn(au.getUsername(),"write poet cache fail");
            }
        }

        user.setPoets(books);
        request.getSession().setAttribute("user",user);
        return 1;
    }

    @Override
    public void logoff(HttpServletRequest request) {
        HttpSession session = request.getSession();
        log.info(session.getAttribute("user").toString() + "logoff");
        session.removeAttribute("user");
    }

    @Override
    @Transactional
    public int regist(String regNumber, String regPassword, String ensureRegPassword, String regEmail, String birDay,
                      String gender, String phone, MultipartFile headImg, Constellation constellation, Zodiac zodiac,
                      HttpServletRequest request, String regName) {
        log.info("accept register request");
        if (regNumber.length() < 6 || null == regNumber || regNumber.trim().length() == 0){
            request.getSession().setAttribute("info", 4);
            log.info("register failed");
            return 4;
        }
        if (!regPassword.equals(ensureRegPassword)){
            request.getSession().setAttribute("info", 3);
            log.info("register failed");
            return 3;
        }
        if (null != authorMapper.loadAuthor(regNumber)){
            request.getSession().setAttribute("info", 2);
            log.info("register failed");
            return 2;
        }
        UploadFile up = new UploadFile(headImg);
        String headImgUrl = up.call();
        if (null ==  headImgUrl){
            headImgUrl = "/img/head/default.png";
        }

        String code = RandomUtil.proRandomNumAndChar(6);

        boolean is = mailUtil.sendEmail(regEmail, code);
        if (!is)
            log.warn("send email failed" + regEmail+ "  "+ code);
        log.info("send email success" + regEmail+ "  "+ code);

        Author regAuthor = new Author(regNumber, regPassword);
        authorMapper.writeAuthor(regAuthor);

        User regUser = new User();
        regUser.setUsername(regName);
        regUser.setLevel(1);
        regUser.setGender(gender);
        regUser.setHeadImg(headImgUrl);
        regUser.setAuthorId(regAuthor.getId());

        try {
            userMapper.writerUser(regUser);

            DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd");
            LocalDate reqBirDay = LocalDate.parse(birDay, dtf);
            LocalDate registTime = LocalDate.now();
            UserDetailInfo detailInfo = new UserDetailInfo(reqBirDay, registTime, phone, constellation, zodiac, regEmail);
            detailInfo.setHometown("四川遂宁");
            detailInfo.setNowAdderss("四川成都");
            detailInfo.setPoetAge(0);
            detailInfo.setUserId(regUser.getId());
            request.getSession().setAttribute("code", code);
            request.getSession().setAttribute("authorId", regAuthor.getId());

            userDetailInfoMapper.writeUserDetailInfo(detailInfo);
            log.info("write user information success  " + regNumber);

            return 1;
        }catch (Exception e){
            request.getSession().setAttribute("info", 0);
            log.warn("write user information failed " + e.toString());
            return 0;
        }
    }

    @Override
    public int ensure(HttpServletRequest request, String ensureCode) {
        HttpSession session = request.getSession();
        int authorId =  (Integer)session.getAttribute("authorId");
        String realCode = (String)session.getAttribute("code");
        if (!realCode.equals(ensureCode)){
            session.setAttribute("ensureInfo", 0);
            return 0;
        }
        log.info("confirm code "+ authorId);
        authorMapper.updateAuthorStatus(authorId);
        return 1;
    }

    @Override
    public void visit(HttpServletRequest request, int goalId) {

        HttpSession session = request.getSession();
        //查询访问量
        Integer visitCount = redisService.loadCacheVisitCount(goalId);
        if (null == visitCount){
            boolean res = redisService.writeVisitCountByUserId(goalId);
            visitCount = 1;
            if (!res)
                log.warn("writeVisitCountByUserId failed " +goalId);
        }
        log.warn("loadCacheVisitCount success " +goalId);
        session.setAttribute("visitCount", visitCount);

        //查询基本数据
        User goalUser = redisService.loadCacheUserByUserId(goalId);
        if (null == goalUser){
            goalUser = userMapper.loadUserAllInfoByUserId(goalId);
            //写入缓存
            boolean res =redisService.writeUserCacheByUserId(goalId, goalUser);
            if (res)
                log.warn("writeUserCacheByUserId failed " + goalId);
        }
        log.warn("loadCacheUserByUserId success " + goalId);
        session.setAttribute("goalUser", goalUser);

        //查询关注用户  共同关注
        User curUser =(User)session.getAttribute("user");
        int curUserId = curUser.getId();
        List<User> goalList = redisService.loadCacheFollowByUserId(goalId);
        if (null == goalList){
            List<Follow> goalFollows = followMapper.loadFollowByUserId(goalId);
            goalFollows.forEach(goalFollow -> {
                User u = userMapper.loadUserAllInfoByUserId(goalFollow.getUserId());
                goalList.add(u);
            } );
            goalList.forEach(info ->{
                redisService.writeFollowCacheByUserId(goalId, info);
            });
        }
        session.setAttribute("goalFollow", goalList);

        List<User> curList = redisService.loadCacheFollowByUserId(curUserId);
        if (null == curList){
            List<Follow> goalFollows2 = followMapper.loadFollowByUserId(curUserId);
            goalFollows2.forEach(goalList2 -> {
                User u = userMapper.loadUserAllInfoByUserId(goalList2.getUserId());
                curList.add(u);
            });
            curList.forEach(info -> redisService.writeFollowCacheByUserId(curUserId, info));
        }

        //获取共同关注
        List<User> commonFollow = redisService.loadCacheComonFollowByAllId(goalId, curUserId);
        if (null == commonFollow){
            commonFollow = redisService.getCacheComonFollowByAllId(goalId, curUserId);
            if (null == commonFollow){
                log.warn("getCacheComonFollowByAllId failed "+ goalId + " "+ curUserId);
            }else {
                commonFollow = redisService.loadCacheComonFollowByAllId(goalId, curUserId);
            }
        }
        session.setAttribute("commonFollow", commonFollow);

        //加载简介
        Introduction introduction = redisService.loadCacheIntroByUserId(goalId);
        if (null == introduction){
            introduction = introductionMapper.loadBriefIntroduction(goalId);
           boolean res = redisService.writeCacheIntroByUserId(goalId, introduction);
           if (!res)
               log.warn("writeCacheIntroByUserId failed " + goalId);
           log.info("writeCacheIntroByUserId success " + goalId);

        }
        session.setAttribute("introduction", introduction);

        //留言板
        List<VisitMessage> messages = redisService.loadCacheVisitMessByUserId(goalId);
        if (null == messages){
            messages = visitMessageMapper.loadVisitMessageByOwnerId(goalId);
            messages.forEach(message ->{
                User u = userMapper.loadUserAllInfoByUserId(message.getOwnerId());
                message.setUser(u);
            });
            boolean res = redisService.writeCacheVisitMessByOwnerId(goalId, messages);
            if (!res)
                log.warn("writeCacheVisitMessByOwnerId failed " + goalId);
            log.info("writeCacheVisitMessByOwnerId success " +goalId);
        }
        session.setAttribute("messages", messages);

        //代表作
        List<Poet> poets = redisService.loadPoetsByAuthorId(goalUser.getAuthorId());
        if (null == poets){
            poets = poetMapper.loadPoetsByAuthorId(goalUser.getAuthorId());
            boolean res = redisService.writePoetCacheByAuthorId(goalUser.getAuthorId(), poets);
            if (!res)
                log.warn("writePoetCacheByAuthorId failed " + goalUser.getAuthorId());
            log.info("writePoetCacheByAuthorId success " + goalUser.getAuthorId());
        }
        session.setAttribute("poets", poets);
    }

    @Override
    public void contactMe(Contact contact) {
        boolean res = mailUtil.sendEmail("3209704905@qq.com", contact.getContent());
        if (res)
            log.info("contactMe failed + "+ contact.getWay());
    }
}
